
#include "GUI.h"
#include "userfont.h"
#include "st7735.h"

//��ILI93xx����������ΪGBR��ʽ��������д���ʱ��ΪRGB��ʽ��
//ͨ���ú���ת��
//c:GBR��ʽ����ɫֵ
//����ֵ��RGB��ʽ����ɫֵ
uint16_t LCD_BGR2RGB(uint16_t c)
{
  uint16_t  r,g,b,rgb;   
  b=(c>>0)&0x1f;
  g=(c>>5)&0x3f;
  r=(c>>11)&0x1f;	 
  rgb=(b<<11)+(g<<5)+(r<<0);		 
  return(rgb);

}

void lcd_setxy(uint8_t x ,uint8_t y)
{
	lcd_set_region(x,y,x,y);
}


void Gui_Circle(uint16_t X,uint16_t Y,uint16_t R,uint16_t fc) 
{//Bresenham�㷨 
    unsigned short  a,b; 
    int c; 
    a=0; 
    b=R; 
    c=3-2*R; 
    while (a<b) 
    { 
        lcd_draw_point(X+a,Y+b,fc);     //        7 
        lcd_draw_point(X-a,Y+b,fc);     //        6 
        lcd_draw_point(X+a,Y-b,fc);     //        2 
        lcd_draw_point(X-a,Y-b,fc);     //        3 
        lcd_draw_point(X+b,Y+a,fc);     //        8 
        lcd_draw_point(X-b,Y+a,fc);     //        5 
        lcd_draw_point(X+b,Y-a,fc);     //        1 
        lcd_draw_point(X-b,Y-a,fc);     //        4 

        if(c<0) c=c+4*a+6; 
        else 
        { 
            c=c+4*(a-b)+10; 
            b-=1; 
        } 
       a+=1; 
    } 
    if (a==b) 
    { 
        lcd_draw_point(X+a,Y+b,fc); 
        lcd_draw_point(X+a,Y+b,fc); 
        lcd_draw_point(X+a,Y-b,fc); 
        lcd_draw_point(X-a,Y-b,fc); 
        lcd_draw_point(X+b,Y+a,fc); 
        lcd_draw_point(X-b,Y+a,fc); 
        lcd_draw_point(X+b,Y-a,fc); 
        lcd_draw_point(X-b,Y-a,fc); 
    } 
	
} 
//���ߺ�����ʹ��Bresenham �����㷨
void Gui_DrawLine(uint16_t x0, uint16_t y0,uint16_t x1, uint16_t y1,uint16_t Color)   
{
int dx,             // difference in x's
    dy,             // difference in y's
    dx2,            // dx,dy * 2
    dy2, 
    x_inc,          // amount in pixel space to move during drawing
    y_inc,          // amount in pixel space to move during drawing
    error,          // the discriminant i.e. error i.e. decision variable
    index;          // used for looping	


	lcd_setxy(x0,y0);
	dx = x1-x0;//����x����
	dy = y1-y0;//����y����

	if (dx>=0)
	{
		x_inc = 1;
	}
	else
	{
		x_inc = -1;
		dx    = -dx;  
	} 
	
	if (dy>=0)
	{
		y_inc = 1;
	} 
	else
	{
		y_inc = -1;
		dy    = -dy; 
	} 

	dx2 = dx << 1;
	dy2 = dy << 1;

	if (dx > dy)//x�������y���룬��ôÿ��x����ֻ��һ���㣬ÿ��y���������ɸ���
	{//���ߵĵ�������x���룬��x���������
		// initialize error term
		error = dy2 - dx; 

		// draw the line
		for (index=0; index <= dx; index++)//Ҫ���ĵ������ᳬ��x����
		{
			//����
			lcd_draw_point(x0,y0,Color);
			
			// test if error has overflowed
			if (error >= 0) //�Ƿ���Ҫ����y����ֵ
			{
				error-=dx2;

				// move to next line
				y0+=y_inc;//����y����ֵ
			} // end if error overflowed

			// adjust the error term
			error+=dy2;

			// move to the next pixel
			x0+=x_inc;//x����ֵÿ�λ���󶼵���1
		} // end for
	} // end if |slope| <= 1
	else//y�����x�ᣬ��ÿ��y����ֻ��һ���㣬x�����ɸ���
	{//��y��Ϊ��������
		// initialize error term
		error = dx2 - dy; 

		// draw the line
		for (index=0; index <= dy; index++)
		{
			// set the pixel
			lcd_draw_point(x0,y0,Color);

			// test if error overflowed
			if (error >= 0)
			{
				error-=dy2;

				// move to next line
				x0+=x_inc;
			} // end if error overflowed

			// adjust the error term
			error+=dx2;

			// move to the next pixel
			y0+=y_inc;
		} // end for
	} // end else |slope| > 1
}



void Gui_box(uint16_t x, uint16_t y, uint16_t w, uint16_t h,uint16_t bc)
{
	Gui_DrawLine(x,y,x+w,y,0xEF7D);
	Gui_DrawLine(x+w-1,y+1,x+w-1,y+1+h,0x2965);
	Gui_DrawLine(x,y+h,x+w,y+h,0x2965);
	Gui_DrawLine(x,y,x,y+h,0xEF7D);
    Gui_DrawLine(x+1,y+1,x+1+w-2,y+1+h-2,bc);
}
void Gui_box2(uint16_t x,uint16_t y,uint16_t w,uint16_t h, uint8_t mode)
{
	if (mode==0)	{
		Gui_DrawLine(x,y,x+w,y,0xEF7D);
		Gui_DrawLine(x+w-1,y+1,x+w-1,y+1+h,0x2965);
		Gui_DrawLine(x,y+h,x+w,y+h,0x2965);
		Gui_DrawLine(x,y,x,y+h,0xEF7D);
		}
	if (mode==1)	{
		Gui_DrawLine(x,y,x+w,y,0x2965);
		Gui_DrawLine(x+w-1,y+1,x+w-1,y+1+h,0xEF7D);
		Gui_DrawLine(x,y+h,x+w,y+h,0xEF7D);
		Gui_DrawLine(x,y,x,y+h,0x2965);
	}
	if (mode==2)	{
		Gui_DrawLine(x,y,x+w,y,0xffff);
		Gui_DrawLine(x+w-1,y+1,x+w-1,y+1+h,0xffff);
		Gui_DrawLine(x,y+h,x+w,y+h,0xffff);
		Gui_DrawLine(x,y,x,y+h,0xffff);
	}
}


/**************************************************************************************
��������: ����Ļ��ʾһ͹��İ�ť��
��    ��: uint16_t x1,y1,x2,y2 ��ť�����ϽǺ����½�����
��    ��: ��
**************************************************************************************/
void DisplayButtonDown(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2)
{
	Gui_DrawLine(x1,  y1,  x2,y1, GRAY2);  //H
	Gui_DrawLine(x1+1,y1+1,x2,y1+1, GRAY1);  //H
	Gui_DrawLine(x1,  y1,  x1,y2, GRAY2);  //V
	Gui_DrawLine(x1+1,y1+1,x1+1,y2, GRAY1);  //V
	Gui_DrawLine(x1,  y2,  x2,y2, WHITE);  //H
	Gui_DrawLine(x2,  y1,  x2,y2, WHITE);  //V
}

/**************************************************************************************
��������: ����Ļ��ʾһ���µİ�ť��
��    ��: uint16_t x1,y1,x2,y2 ��ť�����ϽǺ����½�����
��    ��: ��
**************************************************************************************/
void DisplayButtonUp(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2)
{
	Gui_DrawLine(x1,  y1,  x2,y1, WHITE); //H
	Gui_DrawLine(x1,  y1,  x1,y2, WHITE); //V
	
	Gui_DrawLine(x1+1,y2-1,x2,y2-1, GRAY1);  //H
	Gui_DrawLine(x1,  y2,  x2,y2, GRAY2);  //H
	Gui_DrawLine(x2-1,y1+1,x2-1,y2, GRAY1);  //V
    Gui_DrawLine(x2  ,y1  ,x2,y2, GRAY2); //V
}


void Gui_DrawFont_GBK16(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc, char *s)
{
	unsigned char i,j;
	unsigned short k,x0;
	// int han16_len = sizeof(hz16)/sizeof(struct typFNT_GB162);
	// printf("han 16 font length is %d \r\n",han16_len);
	x0=x;

	while(*s) 
	{	
		if((*s) < 128) 
		{
			k=*s;
			if (k==13) 
			{
				x=x0;
				y+=16;
			}
			else 
			{
				if (k>32) k-=32; else k=0;
	
			    for(i=0;i<16;i++)
				{
					for(j=0;j<8;j++) 
						{
							if(asc16[k*16+i]&(0x80>>j))	
								lcd_draw_point(x+j,y+i,fc);
							else 
							{
								if (fc!=bc) lcd_draw_point(x+j,y+i,bc);
							}
						}
				}
				x+=8;
			}
			s++;
		}
			
		else 
		{
		

			for (k=0;k<han16_len;k++) 
			{
			  if ((hz16[k].Index[0]==*(s))&&(hz16[k].Index[1]==*(s+1)))
			  { 
				    for(i=0;i<16;i++)
				    {
						for(j=0;j<8;j++) 
							{
						    	if(hz16[k].Msk[i*2]&(0x80>>j))	lcd_draw_point(x+j,y+i,fc);
								else {
									if (fc!=bc) lcd_draw_point(x+j,y+i,bc);
								}
							}
						for(j=0;j<8;j++) 
							{
						    	if(hz16[k].Msk[i*2+1]&(0x80>>j))	lcd_draw_point(x+j+8,y+i,fc);
								else 
								{
									if (fc!=bc) lcd_draw_point(x+j+8,y+i,bc);
								}
							}
				    }
				}
				// else
				// {
				// 	printf("can not find words!! %c %c \r\n",*(s),*(s+1));
				// }
			  }
			s+=2;x+=16;
		} 
		
	}
}

void lcd_draw_pic(uint8_t x,uint8_t y,uint8_t x_pixel,uint8_t y_pixel, uint16_t fc,uint16_t bc,char *s)
{
	uint16_t i,j,k;
	uint8_t  x_length = x_pixel/8;
	uint8_t x_yu = x_pixel%8;
	uint16_t fc_temp,bc_temp;
	/*st7735 */
	fc_temp =(fc <<8)|(fc>>8);
	bc_temp =(bc <<8)|(bc>>8);
	if(x_yu!=0)
	{
		x_length = x_length +1;
	}
	lcd_set_region(x,y,x+x_pixel-1,y+y_pixel-1);
	// lcd_set_region(x,y,x+39,y+39);
	for(i=0;i<y_pixel;i++)
	{
		for(j=0;j<x_length;j++)
		{
			for (k=0;k<8;k++)
			{
				if(((*(s+j+i*x_length))>>k)&0x01)
				{
					lcd_write_data16bit(fc_temp);
				}
				else 
				{
					lcd_write_data16bit(bc_temp);
				}
				/*check the last none 8bit byte of one row*/
				if (x_yu!=0 && j==(x_length-1) && k==(x_yu-1))
				{
					// printf("break \r\n");
					break;
				}
			}
		}
	}
}

void lcd_draw_image(uint8_t x,uint8_t y,uint8_t x_e,uint8_t y_e,uint8_t *color)
{
	uint16_t i,j,k;
	uint16_t image_pixel = (x_e-x+1)*(y_e-y+1);
	uint16_t color_temp = 0;
	/*st7735 */
	lcd_set_region(x,y,x_e,y_e);
	for(i=0;i<image_pixel;i++)
	{
		color_temp = ((*(color+i*2))<<8) | (*(color+i*2+1));
        // lcd_write_data((void*)color, image_pixel);

		lcd_write_data16bit(color_temp);
		

	}
}
void lcd_draw_40sigcor(uint8_t x,uint8_t y,uint16_t fc,uint16_t bc,char *s)
{
	uint16_t i,j,k;
	// lcd_set_region(x,y,x+39,y+39);
	for(i=0;i<40;i++)
	{
		for(j=0;j<5;j++)
		{
			for(k=0;k<8;k++)
			{
				if(((*(s+j+i*5))>>k)&0x01)
				{
					lcd_draw_point(x+k+8*j,y+i,fc);
				}
				else 
				{
					lcd_draw_point(x+k+8*j,y+i,bc);
					// lcd_write_data16bit(bc);
				}
			}

		}
	}
}

void lcd_draw_40sigcor1(uint8_t x,uint8_t y,uint16_t fc,uint16_t bc,char *s)
{
	uint16_t i,j,k;
	uint16_t fc_temp,bc_temp;
	fc_temp =(fc <<8)|(fc>>8);
	bc_temp =(bc <<8)|(bc>>8);

	lcd_set_region(x,y,x+39,y+39);
	for(i=0;i<1600;i++)
	{
		fc_temp=(*(s+2*i)<<8) | (*(s+2*i+1));
				lcd_write_data16bit(fc_temp);
					// lcd_draw_point(x+k+8*j,y+i,fc_temp);
				// else if(fc!=bc)
				// {
					// lcd_draw_point(x+k+8*j,y+i,bc);
				// }

	}
}

//��ʾ����
void Gui_DrawFont_char(uint16_t x, uint16_t y, char s)
{
	unsigned char i,j;

			if (s>32) s-=32; else s=0;
	
			    for(i=0;i<16;i++)
				for(j=0;j<8;j++) 
					{
				    	if(asc16[s*16+i]&(0x80>>j))	lcd_draw_point(x+j,y+i,RED);
						else 
						{
							 lcd_draw_point(x+j,y+i,GRAY0);
						}
					}


}
//m^n����
int	oled_pow(uint8_t m,uint8_t n)
{
	uint32_t result=1;	 
	while(n--)result*=m;    
	return result;
}		
//��ʾ2������
//x,y :�������	 
//len :���ֵ�λ��
//size:�����С
//mode:ģʽ	0,���ģʽ;1,����ģʽ
//num:��ֵ(0~4294967295);	 		  
void LCD_ShowNum(uint8_t x,uint8_t y,uint16_t num,uint8_t len)
{         	
	uint8_t t,temp;
	uint8_t enshow=0;						   
	for(t=0;t<len;t++)
	{
		temp=(num/oled_pow(10,len-t-1))%10;
		if(enshow==0&&t<(len-1))
		{
			if(temp==0)
			{
				Gui_DrawFont_char(x+8*t,y,' ');
				continue;
			}else enshow=1; 
		 	 
		}
	 	Gui_DrawFont_char(x+8*t,y,temp+'0'); 
	}
} 


void Gui_DrawFont_GBK24(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc, char *s)
{
	unsigned char i,j;
	unsigned short k;

	while(*s) 
	{
		if( *s < 0x80 ) 
		{
			k=*s;
			if (k>32) k-=32; else k=0;

		    for(i=0;i<16;i++)
			{
			for(j=0;j<8;j++) 
				{
			    	if(asc16[k*16+i]&(0x80>>j))	
					lcd_draw_point(x+j,y+i,fc);
					else 
					{
						if (fc!=bc) lcd_draw_point(x+j,y+i,bc);
					}
				}
			}
			s++;x+=8;
		}
		else 
		{

			for (k=0;k<hz24_num;k++) 
			{
			  if ((hz24[k].Index[0]==(unsigned char)*(s))&&(hz24[k].Index[1]==(unsigned char)*(s+1)))
			  { 
				    for(i=0;i<24;i++)
				    {
						for(j=0;j<8;j++) 
							{
						    	if(hz24[k].Msk[i*3]&(0x80>>j))
								lcd_draw_point(x+j,y+i,fc);
								else 
								{
									if (fc!=bc) lcd_draw_point(x+j,y+i,bc);
								}
							}
						for(j=0;j<8;j++) 
							{
						    	if(hz24[k].Msk[i*3+1]&(0x80>>j))	lcd_draw_point(x+j+8,y+i,fc);
								else {
									if (fc!=bc) lcd_draw_point(x+j+8,y+i,bc);
								}
							}
						for(j=0;j<8;j++) 
							{
						    	if(hz24[k].Msk[i*3+2]&(0x80>>j))	
								lcd_draw_point(x+j+16,y+i,fc);
								else 
								{
									if (fc!=bc) lcd_draw_point(x+j+16,y+i,bc);
								}
							}
				    }
			  }
			}
			s+=2;x+=24;
		}
	}
}
void Gui_DrawFont_Num32(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc, uint16_t num)
{
	unsigned char i,j,k,c;
	// lcd_text_any(x+94+i*42,y+34,32,32,0x7E8,0x0,sz32,knum[i]);
//	w=w/8;
	unsigned char temp = 0;

    for(i=0;i<32;i++)
	{
		for(j=0;j<4;j++) 
		{
			c=*(sz32+num*32*4+i*4+j);
			for (k=0;k<8;k++)	
			{
	
		    	if(c&(0x80>>k))	lcd_draw_point(x+j*8+k,y+i,fc);
				else {
					if (fc!=bc) lcd_draw_point(x+j*8+k,y+i,bc);
				}
			}
		}
	}
}

void Gui_DrawFont_num32(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc, uint16_t num)
{
	unsigned char i,j,k,c;
	// lcd_text_any(x+94+i*42,y+34,32,32,0x7E8,0x0,sz32,knum[i]);
//	w=w/8;
	unsigned char temp = 0;

    for(i=0;i<32;i++)
	{
		for(j=0;j<2;j++) 
		{
			c=*(num32+num*32*2+i*2+j);
			for (k=0;k<8;k++)	
			{
	
		    	if(c&(0x80>>k))	lcd_draw_point(x+j*8+k,y+i,fc);
				else {
					if (fc!=bc) lcd_draw_point(x+j*8+k,y+i,bc);
				}
			}
		}
	}
}
